<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

// 应用公共文件
/**
 * 求两个已知经纬度之间的距离,单位为米
 *
 * @param lng1 $ ,lng2 经度
 * @param lat1 $ ,lat2 纬度
 * @return float 距离，单位米
 */
function get_distance($lng1, $lat1, $lng2, $lat2) {
    // 将角度转为狐度
    $radLat1 = deg2rad($lat1); //deg2rad()函数将角度转换为弧度
    $radLat2 = deg2rad($lat2);
    $radLng1 = deg2rad($lng1);
    $radLng2 = deg2rad($lng2);
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
    return $s;
}

/**
 * 去单双引号
 * @param string $str 需要过滤的字符串
 */
function drop_quote($str){
    $str=preg_replace('/"|\'/', '', $str); //过滤单双引号
    return $str;
}
/**
 * 二维数组根据字段进行排序
 * @params array $array 需要排序的数组
 * @params string $field 排序的字段
 * @params string $sort 排序顺序标志 SORT_DESC 降序；SORT_ASC 升序
 */
function arraySequence($array, $field, $sort = 'SORT_DESC'){
    $arrSort = array();
    foreach ($array as $uniqid => $row) {
        foreach ($row as $key => $value) {
            $arrSort[$key][$uniqid] = $value;
        }
    }
    array_multisort($arrSort[$field], constant($sort), $array);
    return $array;
}
/**
 * 过滤各种关键标签
 * @param $data 要过滤的数据（可以是string或者array格式）
 * @param $function 过滤标签类型（html_decode：已转码字符；html：未转码字符）
 */
function filtration($data,$function=''){
    if(is_array($data)){
        foreach($data as $key=>$str){
            if($function){
                switch($function){
                    case 'html_decode':
                        $str = htmlspecialchars_decode($str);
                        $str = filtr($str);
                        $str = htmlspecialchars($str);
                        break;
                    case 'html':
                        $str = htmlspecialchars($str);
                        $str = filtr($str);
                        $str = htmlspecialchars_decode($str);
                        break;
                }
            }else{
                $str = filtr($str);
            }
            $data[$key] = $str;
        }
    }else{
        if($function){
            switch($function){
                case 'html_decode':
                    $data = htmlspecialchars_decode($data);
                    $data = filtr($data);
                    $data = htmlspecialchars($data);
                    break;
                case 'html':
                    $data = htmlspecialchars($data);
                    $data = filtr($str);
                    $data = htmlspecialchars_decode($data);
                    break;
            }
        }else{
            $data = filtr($data);
        }
    }
    return $data;
}
function filtr($str){
    $str=preg_replace("/\s+/", " ", $str); //过滤多余回车
    $str=preg_replace("/<[ ]+/si","<",$str); //过滤<__("<"号后面带空格)
    $str=preg_replace("/<\!--.*?-->/si","",$str); //注释
    $str=preg_replace("/<(\!.*?)>/si","",$str); //过滤DOCTYPE
    $str=preg_replace("/<(\/?html.*?)>/si","",$str); //过滤html标签
    $str=preg_replace("/<(\/?head.*?)>/si","",$str); //过滤head标签
    $str=preg_replace("/<(\/?meta.*?)>/si","",$str); //过滤meta标签
    $str=preg_replace("/<(\/?body.*?)>/si","",$str); //过滤body标签
    $str=preg_replace("/<(\/?link.*?)>/si","",$str); //过滤link标签
    $str=preg_replace("/<(\/?form.*?)>/si","",$str); //过滤form标签
    $str=preg_replace("/cookie/si","COOKIE",$str); //过滤COOKIE标签
    $str=preg_replace("/<(applet.*?)>(.*?)<(\/applet.*?)>/si","",$str); //过滤applet标签
    $str=preg_replace("/<(\/?applet.*?)>/si","",$str); //过滤applet标签
    $str=preg_replace("/<(style.*?)>(.*?)<(\/style.*?)>/si","",$str); //过滤style标签
    $str=preg_replace("/<(\/?style.*?)>/si","",$str); //过滤style标签
    $str=preg_replace("/<(title.*?)>(.*?)<(\/title.*?)>/si","",$str); //过滤title标签
    $str=preg_replace("/<(\/?title.*?)>/si","",$str); //过滤title标签
    $str=preg_replace("/<(object.*?)>(.*?)<(\/object.*?)>/si","",$str); //过滤object标签
    $str=preg_replace("/<(\/?objec.*?)>/si","",$str); //过滤object标签
    $str=preg_replace("/<(noframes.*?)>(.*?)<(\/noframes.*?)>/si","",$str); //过滤noframes标签
    $str=preg_replace("/<(\/?noframes.*?)>/si","",$str); //过滤noframes标签
    $str=preg_replace("/<(i?frame.*?)>(.*?)<(\/i?frame.*?)>/si","",$str); //过滤frame标签
    $str=preg_replace("/<(\/?i?frame.*?)>/si","",$str); //过滤frame标签
    $str=preg_replace("/<(script.*?)>(.*?)<(\/script.*?)>/si","",$str); //过滤script标签
    $str=preg_replace("/<(\/?script.*?)>/si","",$str); //过滤script标签
    $str=preg_replace("/javascript/si","Javascript",$str); //过滤script标签
    $str=preg_replace("/vbscript/si","Vbscript",$str); //过滤script标签
    $str=preg_replace("/on([a-z]+)\s*=/si","On\\1=",$str); //过滤script标签
    return $str;
}
/**
 * 表格返回过来的基本参数(分页,排序)
 * @param string $defaultSort
 */
function grid_param($defaultSort, $order = 'desc',$pre = '') {
    $result ['sort'] = $pre.input('get.sort',$defaultSort);
    $result ['order'] = input('get.order',$order);
    //$result ['nowPage'] = input('get.page',1); // 当前页
    $result ['rows'] = input('get.rows',20); // 默认列表每页显示行数
    //$result ['firstRow'] = $result ['rows'] * ($result ['nowPage'] - 1); // 起始行数
    return $result;
}
/**
 * 处理搜索关键字
 * @param string $string	处理的字符串
 */
function strip_search_key($string) {
    $string = trim ( $string );
    $string = str_replace ( '*', '%', addcslashes ( $string, '%_' ) );
    $string = str_replace ( '_', '\_', $string );
    return $string;
}
/**
 * 返回JSON数据格式到客户端
 * @param array $data
 */
function return_json($data) {
    exit ( json_encode ( $data ) );
}
/**
 * 节点遍历
 * @param $list
 * @param string $pk
 * @param string $pid
 * @param string $child
 * @param int $root
 * @return array
 */
function list_to_tree($list, $pk='id',$pid = 'pid',$child = '_child',$root=0) {
    // 创建Tree
    $tree = [];
    if(is_array($list)) {
        // 创建基于主键的数组引用
        $refer = [];
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] =& $list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] =& $list[$key];
            }else{
                if(isset($refer[$parentId])) {
                    $parent =& $refer[$parentId];
                    $parent[$child][] =& $list[$key];
                }
            }
        }
    }
    return $tree;
}
/**
+----------------------------------------------------------
 * 字符串截取，支持中文和其他编码
+----------------------------------------------------------
 * @static
 * @access public
+----------------------------------------------------------
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
+----------------------------------------------------------
 * @return string
+----------------------------------------------------------
 */
function msubstr($str, $start=0, $length, $charset="utf-8", $suffix=false) {
    if(mb_strlen($str)<=$length){
        return $str;
    }
    if(function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif(function_exists('iconv_substr')) {
        $slice = iconv_substr($str,$start,$length,$charset);
        if(false === $slice) {
            $slice = '';
        }
    }else{
        $re['utf-8']   = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("",array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice.'...' : $slice;
}
/**
 * 日志
 * @param array $uid 操作者uid
 * @param array $lang 语言包的操作记录描述
 * @param array $mark 操作记录描述替换内容
 */
function markLog($uid,$lang,$mark){
    $log['uid'] = $uid?:0;
    $log['action'] = request()->controller().'/'.request()->action();
    $log['addtime'] = $_SERVER['REQUEST_TIME'];
    $log['ip'] = request()->ip();
    $log['remark'] = setlang($lang,$mark);
    model('Log')->set_log('add',1, $log);
}
/**
 * 执行缓存
 * @param array $data 二维数组，['缓存名称','生成缓存的函数']
 */
function execute_cache($data=[]){
    foreach($data as $key => $value){
        if(!cache($value['0'])){
            call_user_func($value['1']);
            //call_user_func_array($value['1'],[]);
        }
    }
}
/**
 * 调试打印函数
 * @param $string
 */
function p($string,$func = null){
    echo '<pre>';
    if ($func === null){
        if (is_bool($string) || is_null($string) || is_object($string)){
            var_dump($string);
        } else {
            print_r($string);
        }
    } else {
        call_user_func($func,$string);
    }
    echo '</pre>';
}
/**
 * 对密码Sha1加密
 * $key 加密因子，新用户随机生成6位字符串
 * @param string $pwd sha1加密
 * wangruifang 20161016
 */
function pwdSha1($pwd,$key) {
    return sha1(( sha1($pwd) . sha1($key) ));
}

/**
 * 对密码Sha1加密 前端登录专用
 * $key 加密因子，新用户随机生成6位字符串
 * @param string $pwd sha1加密
 * wangruifang 20161016
 */
function loginPwdSha1($pwd,$key) {
	return sha1(( $pwd . sha1($key) ));
}

/**
+----------------------------------------------------------
 * 产生随机字串，可用来自动生成密码 默认长度6位 字母和数字混合
+----------------------------------------------------------
 * @param string $len 长度
 * @param string $type 字串类型
 * 0 字母 1 数字 其它 混合
 * @param string $addChars 额外字符
+----------------------------------------------------------
 * @return string
+----------------------------------------------------------
 */
function rand_string($len=6,$type='',$addChars='') {
    $str ='';
    switch($type) {
        case 0:
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.$addChars;
            break;
        case 1:
            $chars= str_repeat('0123456789',3);
            break;
        case 2:
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZ'.$addChars;
            break;
        case 3:
            $chars='abcdefghijklmnopqrstuvwxyz'.$addChars;
            break;
        case 4:
            $chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借".$addChars;
            break;
        default :
            // 默认去掉了容易混淆的字符oOLl和数字01，要添加请使用addChars参数
            $chars='ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789'.$addChars;
            break;
    }
    if($len>10 ) {//位数过长重复字符串一定次数
        $chars= $type==1? str_repeat($chars,$len) : str_repeat($chars,5);
    }
    if($type!=4) {
        $chars   =   str_shuffle($chars);
        $str     =   substr($chars,0,$len);
    }else{
        // 中文随机字
        for($i=0;$i<$len;$i++){
            $str.= msubstr($chars, floor(mt_rand(0,mb_strlen($chars,'utf-8')-1)),1);
        }
    }
    return $str;
}
/**
 * 获取数组中指定分类的所有子分类ID号
 * @param	array	$arr		数组
 * @param	string	$categoryID	分类ID号,多个用逗号隔开
 * @param	bool	$e			是否循环遍历
 * @param	string	$id			记录字段
 * @param	string	$pid		父级字段
 * @return	string
 * @author	docter4007
 */
function getTreeChildren($arr = array(), $categoryID = '0', $e = true, $id = 'id', $pid = 'pid') {
    $ids = '';
    $categoryID = explode(',',$categoryID);
    foreach ( $arr as $k => $v ) {
//        return $v;
        if (in_array($v[$pid],$categoryID)) {
            $ids .= ',' . $v [$id];
            if ($e && $v) {
                $ids .= getTreeChildren ( $arr, $v [$id], $e, $id, $pid );
            }
        }
    }
    return $ids;
}
function getTreeChildren2($arr = array(), $categoryID = '0', $e = true, $id = 'id', $pid = 'pid') {
    $ids = '';
    $categoryID = explode(',',$categoryID);
    foreach ( $arr as $k => $v ) {
//        return $v;
        if (in_array($v[$pid],$categoryID)) {
            if($ids){
                $ids .= ',' . $v [$id];
            }else{
                $ids = $v [$id];
            }
            if ($e && $v) {
                $ids .= getTreeChildren2 ( $arr, $v [$id], $e, $id, $pid );
            }
        }
    }
    return $ids;
}
/**
 * 获取指定分类的所有子分类ID号
 * @param	string	$categoryID	分类ID号
 * @param	string	$m			数据模型
 * @param	string	$where		查询语句
 * @param	bool	$e			是否循环遍历
 * @param	string	$id			记录字段
 * @param	string	$pid		父级字段
 * @return	string
 * @author	docter4007
 */
function getAllChildcateIds($categoryID = '0', $m, $where = '1', $e = true, $id = 'id', $pid = 'pid') {
    $cate = db ( $m )->where ( $where )->select ();
    $ids = getTreeChildren ( $cate, $categoryID, $e, $id, $pid );
    if($ids) $ids = ','.implode(',', array_filter(array_unique(explode(',', $ids))));
    unset ( $cate );
    return $ids;
}
/**
 * 返回JSON数据格式的提示信息
 * @param    string $msg 提示信息
 * @param    int $status 提示状态
 * @param    array $data 附加信息
 * @param    bool $show 退出状态
 * @return   string
 * @author   docter4007
 */
function back_json($msg = '', $status = 0, $data = array(), $show = false){
    $arr["status"] = $status;
    $arr["msg"] = $msg;
    if ($data) $arr["data"] = $data;
    echo json_encode($arr);
    if (!$show) exit;
}
/**
 * 获取数组中指定分类的所有父分类ID号
 * @param	array	$arr		数组
 * @param	string	$categoryID	分类ID号,多个用逗号隔开
 * @param	bool	$e			是否循环遍历
 * @param	string	$id			记录字段
 * @param	string	$pid		父级字段
 * @return	string
 * @author	docter4007
 */
function getTreeParent($arr = array(), $categoryID = '0', $e = true, $id = 'id', $pid = 'pid') {
    $ids = '';
    if($categoryID) {
        $categoryID = explode(',',$categoryID);
        foreach ($arr as $k => $v) {
            if (in_array($v [$id],$categoryID)) {
                if ( $v[$pid] ) {
                    $ids .= ',' . $v [$pid];
                    if($e){
                        $ids .= getTreeParent ( $arr, $v [$pid], $e, $id, $pid );
                    }
                }
            }
        }
    }
    return $ids;
}
/**
 * 获取指定分类的所有父分类ID号
 * @param	string	$categoryID	分类ID号,多个用逗号隔开
 * @param	string	$m			数据模型
 * @param	string	$where		查询语句
 * @param	bool	$e			是否循环遍历
 * @param	string	$id			记录字段
 * @param	string	$pid		父级字段
 * @return	string
 * @author	docter4007
 */
function getAllParentcateIds($categoryID = '0', $m, $where = '1', $e = true, $id = 'id', $pid = 'pid') {
    $cate = db ( $m )->where ( $where )->select ();
    $ids = getTreeParent ( $cate, $categoryID, $e, $id, $pid );
    if($ids) $ids = ','.implode(',', array_filter(array_unique(explode(',', $ids))));
    unset ( $cate );
    return $ids;
}
/**
 * @param array $data
 * @param $id
 * @param bool|false $myself
 * @return array
 * 通过子级查到所有的父级
 */
function get_all_parent($data=[],$id,$myself=false) {
    $pids = array();
    if ( $myself == true ) {
        array_push($pids, $id);
    }
    foreach ( $data as $key => $value ) {
        if ( $id == $value['id'] && $value['pid'] ) {
            array_push($pids, $value['pid']);
            if ( $value['pid'] ) {
                $p = get_all_parent($data, $value['pid'], false);
                if ( $p ) {
                    $pids = array_merge($pids, $p);
                }
            }
        }
    }
    return $pids;
}
/**
 * @param array $data
 * @param $id
 * @param bool|false $myself
 * @return array
 * 通过子级查到所有的父级的名字
 */
function get_all_parent_names($data=[],$id) {
    $pids = array();
//    if ( $myself == true ) {
//        array_push($pids, $id);
//    }
    foreach ( $data as $key => $value ) {
        if ( $id == $value['id']) {
            array_push($pids, $value['name']);
            if ( $value['pid'] ) {
                $p = get_all_parent_names($data, $value['pid']);
                if ( $p ) {
                    $pids = array_merge($pids, $p);
                }
            }
        }
    }
    return $pids;
}
/**
 * 递归拼装，成树形数组
 * @param    array  $menuArr 数据
 * @param    string $patStr  父级字段 默认为pid
 * @param    string $pid     要查的级别 默认为顶级0
 * @return   array  $result  返回树形数组
 * @author   M
 */
function arr_merge($arr = array(),$patStr='pid',$pid = '0'){
    $result = array();//最总结果的数组
    foreach($arr as $val){
        if($val[$patStr] === $pid){
            $val['child'] = arr_merge($arr,$patStr,$val['id']);
            $result[]=$val;
        }else{
            continue;
        }
    }
    return $result;
}
/**
 * 递归拼装，不成树形数组
 * @param    array  $menuArr 数据
 * @param    string $pk  	 主键字段 默认为id
 * @param    string $patStr  父级字段 默认为pid
 * @param    string $pid     要查的级别 默认为顶级0
 * @return   array  $result  返回数组
 * @author   M
 */
function nottree_merge($array=array(),$pk='id',$patStr='pid',$pid=0,$lv=1){
    $res = array();
    foreach($array as $val){
        if($val[$patStr]==$pid){
            $val['level'] = $lv;
            $res[]=$val;
            $reses = nottree_merge($array,$pk,$patStr,$val[$pk],$lv+1);
            $res = array_merge($res,$reses);
        }
    }
    return $res;
}
/**
 * 迭代检查数组中所有的最终级子元素，并加上 hasSon = 0 标记，其余 hasSon = 1。
 * @param 	array 	$array	  需要检查的数组（只能是二维）
 * @param 	string 	$patStr	  数组中父级ID的键名。	默认：parent_id
 * @param 	string  $pkName	  数组中主键ID的键名。	默认：id
 * @param 	string	$sonMark  最终级子元素标记键名。默认：hasSon
 * @return  array   $result   返回数组
 * @author  M
 */
function finalSon($array=array(),$patStr="pid",$pkName="id",$sonMark='hasSon') {
    foreach ( $array as $key => $val ) {
        $temp = array();
        foreach ( $array as $v ) {
            if ( $val[$pkName] == $v[$patStr] ) {
                $temp[] = $v;
            }
        }
        $array[$key][$sonMark] = empty( $temp ) ? 0 : 1;
    }
    return $array;
}
/**
 * 先处理层级关系，再处理是否有子集
 * @param  	array   $array		需要检查的数组（只能是二维）
 * @param 	string	$pk			数组中主键ID的键名。	默认：id
 * @param 	string 	$patStr		数组中父级ID的键名。	默认：parent_id
 * @param 	string	$sonMark	最终级子元素标记键名。	默认：hasSon
 * @return  array   $result  	返回数组
 * @author  M
 */
function merge_final_son($array=array(),$pk="id",$patStr="pid",$sonMark='hasSon'){
    $temp =  nottree_merge($array);
    $result = finalSon($temp,$patStr,$pk,$sonMark);
    return $result;
}
/**
 * 返回方法
 * @param  	int   	$status		状态 0和1
 * @param 	string	$msg		要返回的文本
 * @param 	array 	$data		要返回的数据
 * @param 	boolean	$is_json	是否返回json格式，默认不返回json格式
 * @author  M
 */
function show_result($status,$msg,$data='',$is_json=false){
    $result['status'] = $status;
    $result['msg'] = $msg?$msg:($status==0?'操作失败，请重试':'操作成功');
    $result['data'] = $data;
    if($is_json){
        exit ( json_encode ( $result ) );
    }else{
        return  $result;
    }
}
/**
 * @param 	string 	$str1	正则验证规则字符串
 * @param 	string 	$str2	字符串
 * @return  bool 验证的结果 1or0
 */
function check_str($str1,$str2){
    return preg_match("/(^{$str1},)|(,{$str1}\b)|(,{$str1},)|({$str1}\b)/",$str2);
}
/**
 * 通过数组和元素id，递归到最顶层父级,返回关联的数组
 * @param	array	$list	数组
 * @param	int		$id		元素id
 * @param	string	$pid	父级关联下标，默认为pid
 * @return	array	$parent	返回关联的数组
 */
function get_option_parent($list,$id,$myself=true){
    $pids = array();
    if($myself and $list[$id]) array_push($pids,$list[$id]);
    $pid = $list[$id]['pid'];
    if(isset($list[$pid])){
        array_push($pids, $list[$pid]);
        $p = get_option_parent($list, $list[$pid]['id'],false);
        if($p){
            $pids = array_merge($pids,$p);
        }
    }
    return array_reverse($pids);
    // 	static $parent=array();
    // 	if($list[$id]){
    // 		$parent[] = $list[$id];
    // 		$id = $list[$id][$pid];
    // 		get_option_parent($list,$id,$pid);
    // 	}
    // 	return array_reverse($parent);
}
//生成订单号
//$type = 1为订单 首字母定位O，2为售后首字母定为C
function buildOrderNo($type=1){
    list($usec, $sec) = explode(" ", microtime());
    $usec = substr(str_replace('0.', '', $usec), 0 ,4);
    $str  = rand_string(2,1);
    
    if($type == 1){
        return 'O'.date("YmdHis").$usec.$str;
    }elseif($type == 2){
        return 'C'.date("YmdHis").$usec.$str;
    }
}

function api_return($code,$data=[],$msg='暂无'){
    $code_config = config('basic.code');
    $return_data['code'] = $code??-2017;
    $return_data['msg'] =  $code_config[$code]??$msg;
    $return_data['data'] = $data;
    return $return_data;
}

/***
 *文章分类缓存
 */

function art_cate_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid,addtime',"asc,desc");
    /* $list['count'] = db('article_cate',[],false)->where($where)->count();
     $list['list'] = db('article_cate',[],false)->where($where)->order($param['sort'].' '.$param['order'])->select();*/
    $list = model('article/ArticleCate')->article_cate_list($where,$param,'','cache');
    cache( 'art_cate_list_'.$where['lang_id'], $list,get_cache_path());
}

function trade_way_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('addtime',"desc");
    /* $list['count'] = db('article_cate',[],false)->where($where)->count();
     $list['list'] = db('article_cate',[],false)->where($where)->order($param['sort'].' '.$param['order'])->select();*/
    $list = model('pay/TradeSet')->trade_way_list($where,$param);
    cache( 'trade_way_list_'.$where['lang_id'], $list,get_cache_path());
}

function deliver_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('addtime',"desc");
    /* $list['count'] = db('article_cate',[],false)->where($where)->count();
     $list['list'] = db('article_cate',[],false)->where($where)->order($param['sort'].' '.$param['order'])->select();*/
    $list = model('order/DeliverSet')->deliver_list($where,$param);
    cache( 'deliver_list_'.$where['lang_id'], $list,get_cache_path());
}

/*******
 * 文章详情缓存
 * @param $id
 */
function art_detail_cache($id,$set_id){
    // return 111;art
    if(!empty($id)&&!empty($set_id)){
        $data['id'] = $id;
        $data['set_id'] = $set_id;
        $data['web_id'] = config('web_id');
//        $data['lang_id'] = config('lang_id');
        $ext_sys_fields = take_cache('ext_sys_fields',false);
        $fields = '*';
        if(!empty($ext_sys_fields[$data['set_id']]['system_fields'])){
            $fields ="id,set_id,".$ext_sys_fields[$data['set_id']]['system_fields'];
        }
        $art_detail = model('article/ArticleList')->article_detail($data,$fields);
        cache( 'art_detail_'.$id, $art_detail,get_cache_path());
    }
}

/*******
 * 链接详情缓存
 * @param $id
 */
function link_detail_cache($id,$set_id){
    if(!empty($id)&&!empty($set_id)) {
        $data['id'] = $id;
        $data['set_id'] = $set_id;
        $data['web_id'] = config('web_id');
        $data['lang_id'] = config('lang_id');
        $fields = '*';
        if(!empty($ext_sys_fields[$data['set_id']]['system_fields'])){
            $fields ="id,set_id,".$ext_sys_fields[$data['set_id']]['system_fields'];
        }
        $link_detail = model('link/Link')->link_detail($data,$fields);
        cache('link_detail_' . $id, $link_detail, get_cache_path());
    }
}
/***
 *产品分类缓存
 */

function product_cate_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid,addtime',"asc,desc");
    $list = model('product/ProductCate')->product_cate_list($where,$param,'','cache');
    cache( 'product_cate_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *相册分类缓存
 */

function alb_cate_list_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid,addtime',"asc,desc");
    //liikentoo 修改缓存
    $list = model('album/albumCategory')->album_cate_list_cache($where,$param,'','cache');
    // $list = model('album/albumCategory')->album_cate_list($where,$param,'','cache');
    cache( 'alb_cate_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *相册缓存
 */

function alb_list_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('sort,addtime',"asc,desc");
    $list = model('album/album')->album_list($where,$param,'','cache');
    cache( 'alb_list_'.$where['lang_id'], $list,get_cache_path());
}


function get_cache_path($is_webid=true,$web_id='',$path=''){
    $option = config('cache');
    $web_id = !empty($web_id)?$web_id:config('web_id');
    if($is_webid == true) $option['path'] = $option['path'].$web_id;
    if(!empty($path)) $option['path'] .= '/'.$path;
    return $option;
}
function get_snop_path($is_webid=true,$web_id='',$path=''){
    $option = config('cache');
    $option['path'] = SNOP_PATH;
    $web_id = !empty($web_id)?$web_id:config('web_id');
    if($is_webid == true) $option['path'] = $option['path'].$web_id;
    if(!empty($path)) $option['path'] .= $path;
    return $option;
}
/***
 *链接分类缓存
 */
function link_cate_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');

    $param = \app\common\model\Base::list_param('orderid');
    /* $list['count'] = db('article_cate',[],false)->where($where)->count();
     $list['list'] = db('article_cate',[],false)->where($where)->order($param['sort'].' '.$param['order'])->select();*/
    $list = model('link/LinkCate')->lists($where,$param,'','cache');
    cache( 'link_cate_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *产品属性缓存
 */

function pro_attr_list_cache($web_id=0,$lang_id=0){
    // return 111;
    $where['web_id'] = !empty($web_id)?$web_id:config('web_id');
    $where['lang_id'] = !empty($lang_id)?$lang_id:config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $list = model('product/ProductAttribute')->product_attribute_list($where,$param,'','cache');
    cache( 'pro_attr_list_'.$where['lang_id'], $list,get_cache_path(true,$web_id));
}

/***
 *产品属性值缓存
 */

function pro_attr_val_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $list = model('product/ProductAttributeVal')->pro_attr_val_list($where,$param,'','cache');
    cache( 'pro_attr_val_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *产品关联的属性及属性值缓存
 */

function pro_attr_val_search_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $list = model('product/ProductAttributeValSearch')->pro_attr_val_search($where,$param,'','cache');
    cache( 'pro_attr_val_search_'.$where['lang_id'], $list,get_cache_path());
}


/***
 *产品详情缓存
 */

function pro_detail_cache($id,$set_id){
    if(!empty($id) && !empty($set_id)){
        $data['id'] = $id;
        $data['set_id'] = $set_id;
        $data['web_id'] = config('web_id');
        $data['lang_id'] = config('lang_id');
        $fields = '*';
        $fields = \app\common\model\base::get_system_fields($set_id);
//        echo $fields;die;
        $pro_detail = model('product/Product')->product_detail($data,$fields);
        cache( 'pro_detail_'.$id, $pro_detail,get_cache_path());
    }
}

/***
 *售后类型缓存
 */

function cus_type_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $list = model('customer/CustomerService')->cus_type_list($where,$param,'','cache');
    cache( 'cus_type_list_'.$where['lang_id'], $list,get_cache_path());
}


/***
 *售后原因缓存
 */

function cus_reason_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $list = model('customer/CustomerService')->cus_reason_list($where,$param,'','cache');
    cache( 'cus_reason_list_'.$where['lang_id'], $list,get_cache_path());
}


/***
 *用户行为缓存
 */

function behavior_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('addtime',"desc");
    $list = model('count/Count')->behavior_list($where,$param,'id','cache');
    //halt($list);
    cache( 'behavior_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *用户行为事件缓存
 */

function event_list_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('addtime',"desc");
    $list = model('count/Count')->event_list($where,$param,'id','cache');
    //halt($list);
    cache( 'event_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *旧文章分类缓存
 */

function old_art_cate_list_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $fields = 'id,name';
    $list = model('data_copy/OldDataCache')->art_cate_list($where,$param,$fields,'cache');
    cache( 'old_art_cate_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *旧文章栏目缓存
 */

function old_art_column_list_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('id',"desc");
    $fields = 'id,name';
    $list = model('data_copy/OldDataCache')->art_column_list($where,$param,$fields,'cache');
    cache( 'old_art_column_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *旧产品分类缓存
 */

function old_pro_cate_list_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('orderid',"desc");
    $fields = 'id,name,pid';
    $list = model('data_copy/OldDataCache')->pro_cate_list($where,$param,$fields,'cache');
    cache( 'old_pro_cate_list_'.$where['lang_id'], $list,get_cache_path());
}


/***
 *旧产品栏目缓存
 */

function old_pro_column_list_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('id',"desc");
    $fields = 'id,name';
    $list = model('data_copy/OldDataCache')->pro_column_list($where,$param,$fields,'cache');
    cache( 'old_pro_column_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *新旧产品属性对应列表缓存
 */

function pro_attr_new2old_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('id',"desc");
    $fields = 'id,old_attr_id,new_attr_id';
    $list = model('data_copy/OldDataCache')->pro_attr_new2old_list($where,$param,$fields,'cache');
    cache( 'pro_attr_new2old_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 *新旧产品属性值对应列表缓存
 */

function pro_attr_val_new2old_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $param = \app\common\model\Base::list_param('id',"desc");
    $fields = 'id,new_attr_id,old_attr_val_id,new_attr_val_id';
    $list = model('data_copy/OldDataCache')->pro_attr_new2old_val_list($where,$param,$fields,'cache');
    cache( 'pro_attr_val_new2old_list_'.$where['lang_id'], $list,get_cache_path());
}
/***
 *网站配置缓存
 */
//function web_set_list_cache(){
//    // return 111;
//    $where['web_id'] = config('WEB_ID');
//    $where['lang_id'] = config('LANG_ID');
//    $param = \app\common\model\Base::list_param('id',"desc");
//    $list = model('WebSet')->web_set_list($where,$param,'','cache');
//    cache( 'web_set_list_'.$where['lang_id'], $list,get_cache_path());
//}
/***
 * 执行缓存
 * $is_lang 是否需要区分语言版本，默认是需要有lang_id的区分，不需要使用的传值false
 * $is_webid 是否需要区分网站，默认是需要有web_id的区分，只有公共的缓存文件，才不需要使用web_id区分，不需要使用的传值false
 * $param 其他的需要拼接的参数 如：id
 */
function take_cache($cache_name = '',$is_lang = true,$is_webid = true,$param=''){
    try{
        $path_cache_name = $cache_name;
        if($is_lang == true){
            $lang_id = config('lang_id');
            $path_cache_name = $path_cache_name.'_'.$lang_id;
        }
        if(!empty($param)){
            $path_cache_name = $path_cache_name.'_'.$param;
        }
        if(cache($path_cache_name ,'',get_cache_path($is_webid)) === false){
            if(function_exists($cache_name.'_cache')){
                call_user_func($cache_name.'_cache',$param);
            }else{
                return [];
            }
        }
        //echo json_encode($path_cache_name);exit;
        return cache($path_cache_name ,'',get_cache_path($is_webid));
    }catch(\Exception $e){
        // throw $e;
        return [];
    }
}
//排序
function list_sort_by($list,$field, $sortby='asc') {
    if(is_array($list)){
        $refer = $resultSet = [];
        foreach ($list as $i => $data){
            $refer[$i] = $data[$field];
        }
        switch ($sortby) {
            case 'asc': // 正向排序
                asort($refer);
                break;
            case 'desc':// 逆向排序
                arsort($refer);
                break;
            case 'nat': // 自然排序
                natcasesort($refer);
                break;
        }
        foreach ( $refer as $key=> $val)
            $resultSet[] = $list[$key];
        return $resultSet;
    }
    return false;
}
/**
 * 鸭梨商城异步更新网站购买的应用
 * 网站
 */
function service_list_cache($web_id=''){
    $web_id = !empty($web_id)?$web_id:config('web_id');
    $business_where = ['web_id'=>$web_id];
    $business = think\Db::connect(config('database.db_config2'))->name('ServiceList')->where($business_where)->field("*")->order('menu_action asc')->select();
    $new_business = [];
    if(!empty($business)){
        $business_type = lang_config('business_type');
        $event_list =  take_cache('service_event',false,false);
        $new_event_list = [];
        if(!empty($event_list)){
            foreach($event_list as $key=>$value){
                $new_event_list[$value['service_id']][] = $value['id'];
            }
            unset($event_list);
        }
        foreach($business as $key=>$value){
            //$value['name'] = $value['model_name'];
            $value['type'] = $value['menu_action'];
            $value['business_type'] = !empty($business_type[$value['type']]['type'])?$business_type[$value['type']]['type']:'';
            unset($value['menu_action']);
            //业务所有的事件
            $value['events'] = !empty($new_event_list[$value['service_id']])?$new_event_list[$value['service_id']]:[];
            $new_business[$value['business_type']] = $value;
        }
        unset($business_type,$new_event_list);
    }
    cache( 'service_list', !empty($new_business)?$new_business:null,get_cache_path(true,$web_id));
    unset($new_business,$business);
}
/**
 * 所有系统字段的缓存列表
 * yali商城异步更新
 */
function field_manage_cache(){
//    echo 11111;exit;
    $field_where = ['status'=>1,'is_system'=>1];
    $field =  think\Db::connect(config('database.db_config2'))->name('FieldsManage')->where($field_where)->field(['web_id','lang_id','addtime','status','set_id','tip','orderid','service_id'],true)->select();
    $new_field_list =  [];
    if(!empty($field)){
        $business_type = lang_config('business_type');
        foreach($field as $key=>$value){
            $value['business_type'] = !empty($business_type[$value['model_type']])?$business_type[$value['model_type']]['type']:'';
            $default_val = [];
            if(!empty($value['val'])){
                $default_val  = explode(',',$value['val']);
            }
            $new_val_arr = [];
            if(in_array($value['field'],['pc_show_status','mobile_show_status'])){
                $val = config('show_statuc');
                if(!empty($val)){
                    foreach($val as $k=>$v){
                        $new_val['id'] = $k;
                        $new_val['value'] = $v;
                        $new_val['checked'] = !empty($default_val) && in_array($k,$default_val) ? true : false;
                        $new_val_arr[] = $new_val;
                    }
                }
            }
            $value['val'] = !empty($new_val_arr)?$new_val_arr:null;
            $new_field_list[$value['id']] = $value;
        }
    }
    cache( 'field_manage', $new_field_list,get_cache_path(false));
}
/**
 * 扩展字段缓存更新
 * 需要区分网站模型
 */
function  extend_fields_cache($web_id=''){
    $web_id = !empty($web_id)?$web_id:config('web_id');
    $field_where = ['is_system'=>0,'web_id'=>$web_id];
    $field =  think\Db::connect(config('database.db_config2'))->name('FieldsManage')->where($field_where)->field(['lang_id','addtime','tip','orderid','service_id'],true)->select();
    $new_field_list =  [];
    if(!empty($field)){
        $business_type = lang_config('business_type');
        $field_id = array_column($field,'id');
        $field_set_relation_arr  = [];
        $field_list = think\Db::connect(config('database.db_config1'))->name('FieldsManageRelation')->where(['field_id'=>['in',$field_id]])->select();
        if(!empty($field_list)){
            foreach ($field_list as $key=>$value){
                $field_set_relation_arr[$value['field_id']][] = $value;
            }
        }

        foreach($field as $key=>$value){
            //$new_field_list = [];
            $value['business_type'] = !empty($business_type[$value['model_type']]['type'])?$business_type[$value['model_type']]['type']:'';
            if(in_array($value['type'],['checkbox','radio','select'])){
//                $val = think\Db::connect(config('database.db_config1'))->name('FieldsManageRelation')->where(['field_id'=>$value['id']])->select();
                $val = !empty($field_set_relation_arr[$value['id']])?$field_set_relation_arr[$value['id']]:[];
                $val_arr = [];
                if(!empty($val)){
                    //获取字段对应的缓存文件
                    // echo json_encode($val);die;
                    $field_cache = cache($value['set_id'].'_'.$value['id'],'',get_cache_path());
                    foreach($val as $b=>$c){
                        $new_val['id'] = $c['id'];
                        $new_val['value'] = $c['val'];
                        $new_val['checked'] = $c['is_checked'] == 1 ? true:false;
                        $new_val['count'] = 0;
                        if(!empty($field_cache) && !empty($field_cache['vals'][$c['id']])){
                            $new_val['count'] = count($field_cache['vals'][$c['id']]);
                        }
                        $val_arr[] = $new_val;
                    }
                    $value['count'] = !empty($field_cache) ? 1 : 0;
                }
                $value['val'] = $val_arr;
            }

            $new_field_list[$value['id']] = $value;
        }
    }
    cache( 'extend_fields', $new_field_list,get_cache_path(true,$web_id));
}
/**
 * 模型缓存
 * 需要区分网站,不需要区分语言版本
 */
function fields_set_cache($web_id=''){
    $web_id = !empty($web_id)?$web_id:config('web_id');
    $field_where = ['web_id'=>$web_id];
    $fields = db('FieldSet',[],false)->where($field_where)->field(['key_id'],true)->order("model_type asc")->select();
    $new_field = [];
    if(!empty($fields)){
        $config = lang_config();
        $business_type = !empty($config['business_type'])?$config['business_type']:'';
//        $field_id = array_column($fields,'id');
        $field_set_relation_arr  = [];
        $field_set_relation = take_cache('extend_fields',false);
        if(!empty($field_set_relation)){
           foreach ($field_set_relation as $key=>$value){
               $field_set_relation_arr[$value['set_id']][] = $value;
           }
        }
//        $event_list = db('field_set_event',[],false)->where(['set_id'=>['in',$field_id]])->field('event_tag,set_id')->select();
//        if(!empty($event_list)){
//            foreach ($event_list as $key=>$value){
//                $event_list_arr[$value['set_id']][] = $value['event_tag'];
//            }
//        }
        foreach($fields as $key=>$value){
            $value['business_type'] = !empty($business_type[$value['model_type']]['type'])?$business_type[$value['model_type']]['type']:'';
            //模型关联的字段
            $new_relation_fiels = [];
            $fields_relation = !empty($field_set_relation_arr[$value['id']])?$field_set_relation_arr[$value['id']]:[];
            if(!empty($fields_relation)){
                foreach($fields_relation as $r=>$e){
                    $new_relation_fiels[$e['id']]['name'] = $e['name'];
                    $new_relation_fiels[$e['id']]['source_id'] = $e['source_id']??'';
                    $field_use_cache = cache($e['set_id'].'_'.$e['id'],'',get_cache_path());
                    $new_relation_fiels[$e['id']]['count'] = !empty($field_use_cache)?1:0;
                    $new_relation_fiels[$e['id']]['is_system'] = 0;
                }
            }
            $value['fields'] = !empty($new_relation_fiels)?$new_relation_fiels:null;
            unset($fields_relation,$new_relation_fiels);
            $new_field[$value['id']] = $value;
        }
        unset($fields,$field_set_relation,$field_set_relation_arr,$config);
    }
    cache( 'fields_set', !empty($new_field)?$new_field:null,get_cache_path(true,$web_id));
    if(!empty($new_field)) ext_sys_fields_cache();
}
/**
 * 扩展字段缓存
 * 需要区分网站,不需要区分语言版本
 */
function extend_fields_vals_cache($primary_id=''){
    $field_where = ['web_id'=>config('web_id')];
    if(!empty($primary_id))$field_where['primary_id'] = $primary_id;
    $fields = db('ExtendFieldsVals')->where($field_where)->select();
    $new_field = [];
    if(!empty($fields)){
        foreach($fields as $n=>$v){
            if(strpos($v['val'],',')) {
                $new_field[$v['primary_id']][$v['field_id']] = explode(',',$v['val']);
            }else{
                $new_field[$v['primary_id']][$v['field_id']] = $v['val'];
            }
        }
    }
    //exit;
    foreach($new_field as $k=>$val){
        cache( 'extend_fields_vals_'.$k, $new_field[$k],get_cache_path());
    }

}
/*更新部分扩展字段缓存*/
function update_extend_fields_val_cache($data){
    //$exten_fields_vals = take_cache('extend_fields_vals_'.$data['primary_id'],false);
    if(strpos($data['val'],',')) {
        $exten_fields_vals[$data['field_id']] = explode(',',$data['val']);
    }else{
        $exten_fields_vals[$data['field_id']] = $data['val'];

    }
    cache( 'extend_fields_vals_'.$data['primary_id'], $exten_fields_vals,get_cache_path());
}
/*区分扩展字段缓存*/
function ext_sys_fields_cache(){
//    field_manage_cache();
//    fields_set_cache();
    $field_manage = take_cache('field_manage',false,false);
    $fields_set = take_cache('fields_set',false);
    $new_manage = $relation_manage = [];
    if(!empty($field_manage)){
        foreach($field_manage as $m=>$v){
            if(empty($v['relation_action'])){
                $new_manage[]=$m;
            }else{
                //记录关联信息
                $relation_manage[] = $m;
            }
        }
    }

    $new_list = [];
    if(!empty($fields_set)){
        foreach($fields_set as $n=>$val){
            if(!empty($val['fields'])){
                $new_list[$n]['system_fields'] = '';
                $new_list[$n]['extend_fields'] = '';
                foreach($val['fields'] as $k=>$value){
                    if(in_array($k,$new_manage)){
                        //$new_list[$n]['system'][] = $field_manage[$k]['field'];
                        $new_list[$n]['system_fields'] .= $field_manage[$k]['field'].',';
                    }else if((!empty($relation_manage) && !in_array($k,$relation_manage)) || empty($relation_manage)){
                        //$new_list[$n]['extend'][] = $k;
                        $new_list[$n]['extend_fields'] .= $k.',';
                    }
                }

                if(!empty($new_list[$n]['system_fields'])){ $new_list[$n]['system_fields'] = rtrim($new_list[$n]['system_fields'],',');}
                if(!empty($new_list[$n]['extend_fields'])){ $new_list[$n]['extend_fields'] = rtrim($new_list[$n]['extend_fields'],',');}
            }
        }
    }
    cache('ext_sys_fields', $new_list,get_cache_path());
}
/**
 * 事件缓存
 */
function service_event_cache(){
    //所有事件
    $e = ['EVENT_TYPE_FROM_COMMENT','EVENT_TYPE_ARTICLE_COMMENT','EVENT_TYPE_LINK_COMMENT','EVENT_TYPE_ALBUM_COMMENT'];
    $event_where = ['status'=>1,'identifying'=>['not in',$e]];
    $event_list =  think\Db::connect(config('database.db_config2'))->name('Event')->where($event_where)->field(['status','addtime'],true)->select();
    $new_event =  [];
    if(!empty($event_list)){
        $field_id = array_column($event_list,'id');
        $event_list_arr = [];
        $event_lists  =  think\Db::connect(config('database.db_config2'))->name('FieldsManage')->where(['event_id'=>['in',$field_id]])->field('id,event_id')->select();
        if(!empty($event_lists)){
            foreach ($event_lists as $key=>$value){
                $event_list_arr[$value['event_id']][] = $value['id'];
            }
        }
        foreach($event_list as $key=>$value){
            //事件关联的字段
            $value['fields'] =  !empty($event_list_arr[$value['id']])?$event_list_arr[$value['id']]:[];
            $value['id'] = $value['identifying'];
            $new_event[$value['id']] = $value;
        }
    }
    cache( 'service_event', $new_event,get_cache_path(false));
}
/**
 * 订单设置缓存
 */
function order_set_cache(){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $list = model('order/OrderSet')->get_order_set($where);
    cache( 'order_set_'.$where['lang_id'], $list,get_cache_path());
}
/**
 * 支付设置缓存
 */
function payment_cache($type){
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $where['pay_way'] = $type;
    $payment_type = lang_config('payment_type');
    $list = model('order/OrderSet')->get_payment($where);
    $type_name = $payment_type[$type]['type'];
    //print_r($list);
    cache( 'payment_'.$type_name.'_'.$where['lang_id'], $list,get_cache_path());
}


/*
*随机生成32位字符串
*/
function create_random($namespace = 'yali',$len = 32) {
    static $guid = '';
    $uid = uniqid('', true);
    $data = $namespace;
    $data .= $_SERVER['REQUEST_TIME'];
    if(!empty($_SERVER['HTTP_USER_AGENT'])) $data .= $_SERVER['HTTP_USER_AGENT'];
    $data .= $_SERVER['REMOTE_ADDR'];
    $data .= $_SERVER['REMOTE_PORT'];
    $hash = hash('ripemd128', $uid . $guid . md5($data));
    if($len == 32)
    {
        $guid = substr($hash,0,8).substr($hash,8,6).substr($hash,7,6).substr($hash,20,12);
    }else{
        $guid = substr($hash,0,3).substr($hash,8,5);
    }

    return $guid;
}

/**
 * 发送模板短信
 * @param to 短信接收手机号码集合,用英文逗号分开
 * @param data 内容数据 array('参数1','参数2','参数3'....);
 * @param $type 鸭梨短信模板id
 * @param $param 拓展传参
 * @author wangruifang
 */
//public function send_sms($to,$data,$type='1'){
function single_send_sms($to,$data,$type='1',$param=[]){
    //debug('begin');
    ///检测该网站的短信情况
    $check_sms = model('Common/ConfigSet')->check_sms($param);
    $mobile_num = count(explode(",",$to));
    if(($check_sms - $mobile_num) < 0){
        return ['status'=>0,'msg'=>'该站的短信不足请充值'];
    }
    $sms_set = model('Common/ConfigSet')->get_sms();

    $sms_temp_list = model('Common/ConfigSet')->get_sms_temp("is_delete=0");
    foreach($sms_temp_list as $k=>$v){
        $sms_temp[$v['id']] = $v;
    }
    $sms_type = $sms_temp[$type]['template_id']??1;
    $mail = new \sms\Rest($sms_set['api_url'],$sms_set['api_port'],$sms_set['account_version'],$sms_set['account_sid'],$sms_set['account_token'],$web_app_info['appid']??$sms_set['appid']);
    //发送短信
    $smsApi = $mail->sendTemplateSMS($to,$data,$sms_type);
    //获取短信模板记录日志
    $QuerySMSTemplate = $mail->QuerySMSTemplate($sms_type);
    if($QuerySMSTemplate->statusCode == '000000'){
        $temp = $QuerySMSTemplate->TemplateSMS;
    }
    //return $temp[0]->content;
    $content_bei = $sms_temp[$type]['content']??'';
    $content = $temp[0]->content??$content_bei;
    //debug('begin2');
    if($smsApi['statusCode'] == '000000'){
        $return['msg'] = '发送成功';
        $return['status'] = 1;
        //更改条数
        model('Common/ConfigSet')->change_sms($mobile_num,$param);
    }else{
        $return['msg'] = $smsApi['statusMsg'];
        $return['status'] = 0;
    }
    //$content = $sms_temp[$type]['content']??'';
    foreach($data as $kk=>$vv){
        $n = $kk+1;
        $content = str_replace("{".$n."}",$vv,$content);
    }
    $phone = explode(',',$to);
    //debug('begin3');
    foreach($phone as $k2=>$v2){
        $save = [
            'web_id'=>config('web_id'),
            'lang_id'=>config('lang_id'),
            'phone'=>$v2,
            'content'=>$content,
            'status'=>$return['status'],
            'remark'=>$return['status']==0?$return['msg']:'',
            'addtime'=>request()->time(),
            'sendtime'=>request()->time(),
        ];
        model('Common/ConfigSet')->set_sms_log('add',1, $save);
    }
    //debug('begin4');
    //$smsApi['time'] = debug('begin','begin4').','.debug('begin','begin2').','.debug('begin2','begin3').','.debug('begin3','begin4');
    return $return;
}


/**
 * 单次邮件发送函数
 * @param string $to    接收邮件者邮箱
 * @param string $subject 邮件主题
 * @param string $message    邮件内容
 * @param string $template 模板名
 * @param string $attachment 附件列表
 * @param string $ssl  ssl状态
 * @param string $from  邮件发送服务器参数，不传默认调用系统配置
 * $param array $param 拓展参数
 * @return array
 */
function single_send_mail($to, $subject = '', $message = '', $template = null , $attachment = null , $ssl = false , $from = null,$param=[]){
    try{
        $result = model('Common/ConfigSet')->send_mail($to, $subject, $message, $template, $attachment, $ssl, $from,$param);
        if($result['status'] == 1){
            $return['msg'] = '发送成功';
            $return['status'] = 1;
            $save = [
                'web_id' => config('web_id'),
                'lang_id' => config('lang_id'),
                'send_address'=>$to,
                'from_address'=>$from['from_mail']??'',
                'title'=>$subject,
                'content'=>$message,
                'status'=>$return['status'],
                'remark'=>$return['status']==0?$return['msg']:'',
                'addtime'=>request()->time(),
                'sendtime'=>request()->time(),
            ];
            model('Common/ConfigSet')->set_email_log('add',1, $save);
        }else{
            $return['msg'] = $result['msg'];
            $return['status'] = 0;
        }
        return $return;
    }catch (\Exception $e){
        return  false;
    }
 }


/**
 * 七牛图片路径转化
 * @param	string	$val	图片路径
 * @param	string	$w		宽
 * @param	string	$h		高
 * @param	string	$type	缩放类型
 * @param	string	$default   默认值
 * @return	string
 * @author	docter4007
 */
function showqiniu_Pic($val = null, $type = null, $default=''){
    if ($val) {
        if(substr($val, 0, 1) == '.'){
            $val = 'http://oixavq5ec.bkt.clouddn.com'.ltrim($val, '.');
        }else{
            $val = 'http://oixavq5ec.bkt.clouddn.com'.$val;
        }
        return $val;
    }
    return $default;
}


/**
 * 返回所有上传文件路径
 * @param unknown $web_id 网站ID
 * @param unknown $model_name 上传文件名
 * @param unknown $product_id ID
 * @param unknown $file_name 文件名
 * @return string
 */
function all_upload_file_path($web_id,$model_name,$file_name='0',$img_name){
    $path = lang(config('ALL_UPLOAD_FILE_PATH'),array('web_id'=>$web_id,'model_name'=>$model_name,'file_name'=>$file_name,'img_name'=>$img_name));
    return $path;
}

/**
 * 区域缓存
 */
function region_list_cache(){
    $list = cache( 'region_list');
    if(!$list){
        $list = model('ConfigSet')->region_list();
    }
    return $list;
}

/**
 * 返回带域名的路径:格式 './xxx'
 */
function return_domain_url($url=''){
    $domain = $_SERVER['HTTP_HOST'];
    if($url) $domain = $domain.substr($url,1);
    $domain = preg_http($domain);
    return $domain;
}
function preg_http($domain){
//    $preg='|^http://|';  //正则，匹配以http://开头的字符串
    $preg="/^(http:\/\/|https:\/\/).*$/";  //正则，匹配以http://开头的字符串
    if(!preg_match($preg,$domain)) {  //如果不能匹配
        $domain = 'http://'.$domain;
    }
    return $domain;
}

//获取一级域名
function get_suffix($domain){
    $suffix_arr = array('.com','.top','.cn','.net','.cc','.hk','.xyz','.co','.org','.wang','.me','.pw','.la','.asia','.biz','.mobi','.gov','.name','.info','.tm','.tv','.tel','.us','.tw','.ren','.site','.edu','.jp','.uk','.int','.mil','.com.cn','.cn.com','.gov.cn','.net.cn','.org.cn','.com.hk','.中国','.公司','.网络','.cd','.travel','.pro','.museum','.tt','.coop','.idv','.post','.jobs','.cat','.club','.tech','.zone','.win','.vip','.tax','.vivo');
    //$num = -1 ;
    foreach($suffix_arr as $k=>$v){
        $arrStr = explode($v, $domain);
        if ($arrStr[count($arrStr)-1] == "") {
            $suffix = $v;
            $num = -strlen($suffix);
        }
    }
    if(isset($suffix)){
        $domain_head = substr_replace($domain,'',$num);
        $arr = explode('.',$domain_head);
        $domain_main = $arr[count($arr)-1];
        $result = $domain_main.$suffix;
        return $result;
    }else{
        return $domain;
    }
}

/**
 * 会员支付后查看优惠信息
 */
function updateMemberDiscount($order_id,$status='0',$time=NOW_TIME){
    if($order_id){
        $order = db('Order')->where('id',$order_id)->field('order_no,shop_discount_tag')->find();
        if($order['shop_discount_tag']){
            editActivityStatus($order['shop_discount_tag'],$status='0',$time=NOW_TIME);
        }
        $order_list = M('ProductOrderList')->where("discount_tag!='' and order_id={$order_id}")->getField('discount_tag',true);
        if(!empty($order_list)){
            foreach($order_list as $key=>$value){
                editActivityStatus($value,$status='0',$time=NOW_TIME);
            }
        }
    }
}

/**
 * 系统消息
 */
function member_system_message($uid='0',$content,$is_system='0',$type='0',$order_no=''){
    $message['uid'] = $uid?$uid:0;
    $message['content'] = $content?$content:'';
    $message['type'] = $type;
    $message['order_no'] = $order_no;//站内消息可绑定订单好
    $message['is_system'] = $is_system;
    $message['is_read'] = 0;
    $message['web_id'] = config('web_id');
    $message['lang_id'] = config('lang_id');
    $message['addtime'] = NOW_TIME;
    db('MemberSystemMessage')->insert($message);
}

/**
 * 支付成功通知卖家
 */
function inform_saler_for_sms($order_no){
    $is_sms = M('WebSet')->where(array('web_id'=>C('WEB_ID'),'lang_id'=>C('LANG_ID')))->getField('is_pay_sms');
    if($is_sms) {
        $where['po.web_id'] = C('WEB_ID');
        $where['po.lang_id'] = C('LANG_ID');
        $where['m.is_phone'] = 1;
        $where['po.order_no'] = array( 'in', $order_no );

        $data = M('ProductOrder po')
            ->join(C('DB_PREFIX') . 'member m on po.shop_uid=m.uid')
            ->where($where)
            ->field('po.order_no,m.phone,po.status,po.addtime,po.paytime,po.pay_way')
            ->select();

        foreach ( (array)$data as $k => $v ) {
//			if ( $v['status'] == 0 && $v['pay_way'] != 6 ) {     //货到付款不走这里
//				$content = array( $v['order_no'], date('Y-m-d H:i:s', $v['addtime']) );
//				//				send_sms_normal($v['phone'],$content,'2');		//下单成功
//				send_sms($v['phone'], $content, '2');        //下单成功
//			}

            if ( $v['status'] == 1 ) {
                $content = array( $v['order_no'], date('Y-m-d H:i:s', $v['paytime']) );
                send_sms($v['phone'], $content, '3');        //支付成功
            }

            if ( $v['status'] == 0 && $v['pay_way'] == 6 ) {     //货到付款走这里
                $content = array( $v['order_no'], date('Y-m-d H:i:s', time()) );
                //				send_sms_normal($v['phone'],$content,'2');		//下单成功
                send_sms($v['phone'], $content, '2');        //下单成功
            }
        }

//		return $data;
    }
}

function editActivityStatus($discount_tag,$status='0',$time=NOW_TIME){
    $discount_tag = explode('_',$discount_tag);//0类型，1id
    switch($discount_tag[0]){
        case 'proCou':
            //优惠券
        case 'freeCou':
            //优惠券
        case 'shopCou':
            //店铺券
            M('MemberReceiveCoupons')->where(array('id'=>$discount_tag[1]))->save(array('status'=>$status,'use_time'=>$time));
            break;
    }
}

//选择语言配置  $key为键值,$lang为语言版配置
function lang_config($key="",$lang_id = 0){
    
    $all = [1=>'cn',2=>'en'];
    $version = (isset($all[$lang_id]))? $all[$lang_id]:$all[1];
    $file = 'basic_config_'.$version;
    $config = (trim($key))?config($file.".".$key):config($file);
    
    return $config;
}


/**
 * 获取语言定义(不区分大小写)
 * @param string|null   $name 语言变量
 * @param array         $vars 变量替换
 * @param string        $range 语言作用域
 * @return mixed
 */
function  get_lang($name=null,$vars=[],$range=''){
    static $lang = [];
    static $lang_path = [];
    $langVersion = config('range');
    $range = !empty($range)?(isset($langVersion[$range])?$langVersion[$range]:request()->langset()):request()->langset();
    $path = APP_PATH  .request()->module();
    if (!isset($lang[$range]) && !isset($lang_path[$path])) {
        $lang[$range] = $range;
        $lang[$path] = $path;
        \think\Lang::load([
            // 加载系统语言包
            THINK_PATH . 'lang' . DS . $range . EXT,
            APP_PATH . 'lang' . DS .$range. EXT,
            // 加载当前模块语言包
            $path .DS. 'lang' . DS . $range . EXT,
        ]);
    }
    return \think\Lang::get($name,$vars);
}

//判断消息订阅类型开启 paulbi $type是类型值 对应basic_config的prompt_type;
function take_msg($type,$web_id,$lang_id = 1){
    $field = 'prompt_email,email_action,prompt_sms,sms_action,prompt_msg,msg_action';
    $conf = db('order_set')->where(['web_id'=>$web_id,'lang_id'=>$lang_id])->field($field)->find();
    //echo json_encode($conf);exit;
    $new_conf = ['email'=>0,'sms'=>0,'msg'=>0];
    if($conf){
        if($conf['prompt_email'] == 1){//开启了email
            $conf['email_action'] = explode(',',$conf['email_action']);
            if(in_array($type, $conf['email_action'])){
                $new_conf['email'] = 1;
            }
        }

        if($conf['prompt_sms'] == 1){//开启了sms
            $conf['sms_action'] = explode(',',$conf['sms_action']);
            if(in_array($type, $conf['sms_action'])){
                $new_conf['sms'] = 1;
            }
        }

        if($conf['prompt_msg'] == 1){//开启了站内提醒
            $conf['msg_action'] = explode(',',$conf['msg_action']);
            if(in_array($type, $conf['msg_action'])){
                $new_conf['msg'] = 1;
            }
        }
    }

    return $new_conf;
}
//判断订单操作人的类型，在某些操作时前后端双方共用接口的：比如取消订单。只有在商家取消订单的时候才执行take_msg方法发送消息。
function get_operator_type($uid,$order_no){
    $order_uid = db('order')->where(['order_no'=>$order_no])->value('uid');
    if($order_uid){
        if($order_uid != $uid){
            $info = 1;//不是下单人，可以执行take_msg
        }else{
            $info = 0;
        }
    }else{
        $info = 0;
    }
    return $info;
}
function isMobile(){
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset ( $_SERVER ['HTTP_X_WAP_PROFILE'] ))
        return true;
    // 此条摘自TPM智能切换模板引擎，适合TPM开发
    if (isset ( $_SERVER ['HTTP_CLIENT'] ) && 'PhoneClient' == $_SERVER ['HTTP_CLIENT'])
        return true;
    // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset ( $_SERVER ['HTTP_VIA'] ))

        // 找不到为flase,否则为true
        return stristr ( $_SERVER ['HTTP_VIA'], 'wap' ) ? true : false;
    // 判断手机发送的客户端标志,兼容性有待提高
    if (isset ( $_SERVER ['HTTP_USER_AGENT'] )) {
        $clientkeywords = array (
            'nokia',
            'sony',
            'ericsson',
            'mot',
            'samsung',
            'htc',
            'sgh',
            'lg',
            'sharp',
            'sie-',
            'philips',
            'panasonic',
            'alcatel',
            'lenovo',
            'iphone',
            'ipod',
            'blackberry',
            'meizu',
            'android',
            'netfront',
            'symbian',
            'ucweb',
            'windowsce',
            'palm',
            'operamini',
            'operamobi',
            'openwave',
            'nexusone',
            'cldc',
            'midp',
            'wap',
            'mobile'
        );
        // 从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match ( "/(" . implode ( '|', $clientkeywords ) . ")/i", strtolower ( $_SERVER ['HTTP_USER_AGENT'] ) )) {
            return true;
        }
    }
    // 协议法，因为有可能不准确，放到最后判断
    if (isset ( $_SERVER ['HTTP_ACCEPT'] )) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos ( $_SERVER ['HTTP_ACCEPT'], 'vnd.wap.wml' ) !== false) && (strpos ( $_SERVER ['HTTP_ACCEPT'], 'text/html' ) === false || (strpos ( $_SERVER ['HTTP_ACCEPT'], 'vnd.wap.wml' ) < strpos ( $_SERVER ['HTTP_ACCEPT'], 'text/html' )))) {
            return true;
        }
    }
    return false;
}

function isWeixin() {
    $url = $_SERVER['HTTP_HOST'];
    $url_arr = explode('.',$url);
    if ((strpos ( $_SERVER ['HTTP_USER_AGENT'], 'MicroMessenger' ) !== false || ( strpos ( $_SERVER ['HTTP_USER_AGENT'], 'Windows Phone' ) !== false) && $url_arr[0] == 'wx' ) ){
            return true;
    }
    return false;
}

/*******
 *
 * 服务器单个文件上传
 */

 function one_upload($folder = '',$config = []){
    // 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('voice');
    // 移动到框架应用根目录/public/uploads/ 目录下
     if(empty($config)){
         $config = [
             'size' =>   2097152,//2M
             'ext'  =>   'mp3,wav,acc,png,jpg,jpeg,gif,bmp,xls,xlsx,doc,docx,ppt,pptx,pdf,txt',
         ];
     }

    $info = $file->validate($config)->move($folder);
//     var_dump($info);exit;
    if($info){
        // 成功上传后 获取上传信息
        // 输出 jpg
//        echo $info->getExtension();
        // 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
//        echo $info->getSaveName();
        // 输出 42a79759f284b767dfcb2a0197904287.jpg
        $fileinfo['status'] = 1;
        $fileinfo['filename'] =$folder.$info->getSaveName();
         return $fileinfo;
    }else{
        // 上传失败获取错误信息
        $fileinfo['status'] = -1;
        $fileinfo['msg'] = $file->getError();
        return $fileinfo ;
    }
}

/*******
 *
 * 服务器多个文件上传
 */
 function more_upload($folder = ''){
     $folder =!empty($folder)?$folder:'uploadfile/'.config('web_id');
    // 获取表单上传文件
    $files = request()->file('image');
     $config = [
         'size' =>   2097152,//2M
         'ext'  =>   'png,jpg,jpeg,gif,bmp,xls,xlsx,doc,docx,ppt,pptx,pdf,txt',
     ];
    foreach($files as $file){
        // 移动到框架应用根目录/public/uploads/ 目录下
        $info = $file->validate($config)->move($folder);
        if($info){
            // 成功上传后 获取上传信息
            // 输出 jpg
            return $info;
        }else{
            // 上传失败获取错误信息
            echo $file->getError();
        }
    }
}
function rsa_key_cache(){
    $key = think\Db::connect(config('database.db_config2'))->name('Web')->where(['id'=>config('web_id')])->field(['public_key','private_key'])->find();
    if(!empty($key)){
        cache('rsa_key',$key,get_cache_path());
    }
}

//会员权限合并用的
function member_arr_merge($arr = array(),$patStr='pid',$pid = '0'){
    $result = array();//最总结果的数组
    foreach($arr as $val){
        if($val[$patStr] == $pid){
            $val['child'] = arr_merge($arr,$patStr,$val['id']);
            $result[]=$val;
        }else{
            continue;
        }
    }
    return $result;
}

//记录行为日志 $content = 标题。$type = 1为添加，2是编辑，详细看make_msg中的定义
//$content 内容标题，$id id值，$custom是否自定义开关，大于0是开
function make_log($content,$id,$type=1,$custom=0){
    $filename = date('Y-m-d');
    $info_name = get_lang('TITLE',['content'=>$content]);
    $make_msg = ['username'=>config('username'),'module'=>request()->module(),'content'=>$info_name,'type'=>$type];
    
    if($custom > 0){
        $msg = \app\common\model\Base::make_msg($make_msg,$content);
    }else{
        $msg = \app\common\model\Base::make_msg($make_msg);
    }

    if($msg!==false){
        $log_info = ['filename'=>$filename,'module'=>$make_msg['module'],'info_id'=>$id,'msg'=>$msg];
        \app\common\model\Base::write_user_log($log_info);
    }

}

//根据积分开关情况，返回实际可用的积分。Paulbi
//参数$data['web_id'],$data['lang_id'],$data['uid']
function open_integral($data=[]){
    //判断积分开启情况
    $wheresql = 'web_id='.$data['web_id'].' and lang_id ='.$data['lang_id'] ;
    $credit_config = model('member/MemberCredit')->get_config($wheresql,'is_open_credit,is_shopping_interaction,credit_scale,proportion');
    $is_open_credit = $credit_config['is_open_credit'];//判断是否开启积分,总开关
    $is_shopping_interaction = $credit_config['is_shopping_interaction'];//判断是否开启消费积分
    $all_credit = db('member',[],false)->where(['uid'=>$data['uid']])->field('consume_credit,interact_credit')->find();//获取uid的消费积分和互动积分

    if($is_open_credit ==1 && $is_shopping_interaction ==1){//如果同时开启了积分和消费积分，获取设置的积分比例值
        $consume_credit = (!empty($all_credit))?$all_credit['consume_credit']:0;//如果开启了，消费积分和互动积分分开。
    }elseif($is_open_credit ==1 && $is_shopping_interaction ==0){//如果只开启了积分，那么积分=消费积分+互动积分
        $consume_credit = (!empty($all_credit))?($all_credit['consume_credit']+$all_credit['interact_credit']):0;
    }else{
        $consume_credit = 0;
    }
    
    return $consume_credit;//根据积分开关，计算出最后可用的积分。
}

//积分规则 Paulbi
//参数$data['web_id'],$data['lang_id'],$data['uid'],$data['total'],$data['paid_price'],$data['exchange_score']
function integral($data){
    $credit = open_integral($data);
    if(empty(intval($data['exchange_score']))){
        return false;
    }
    if(empty($credit)){
        return -11642;
        //return api_return('积分为0');
    }
    if(intval($data['exchange_score']) > $credit){//exchange_score是传进来的要兑换的积分
        return -10959;
        //return api_return(-10959);
    }
    $wheresql = 'web_id='.$data['web_id'].' and lang_id ='.$data['lang_id'] ;
    $credit_config = model('member/MemberCredit')->get_config($wheresql,'is_open_credit,is_shopping_interaction,credit_scale,proportion');
    $credit_scale = $credit_config['credit_scale'];//获取兑换比例
    $propor = $credit_config['proportion']/100;//积分抵购比例
    
    $exchange_price = (intval($data['exchange_score'])/$credit_scale)*1*100;//当前传入的积分可兑换多少钱，单位是分

    $upper_money = $data['total']*100* $propor;//$data['total']是订单总价（含合并下单）能兑换的上额 单位是分

    if($exchange_price > $upper_money){//如果可兑换的钱大于实付价钱
        $final_score = $upper_money/100*$credit_scale;//本次实际兑换消耗了的积分
    }else{//否则
        $final_score = intval($data['exchange_score']);//本次兑换消耗了多少积分，传多少兑多少
        //$data['total'] = ($data['total'] - $exchange_price);//实付为原来的实付金额减去兑换的金额
    }
    $per_order_propor = $data['paid_price']/$data['total'];//每张订单所占的积分比例
    $per_order_ctedit = $final_score*$per_order_propor;//每张订单占的积分
    return $info = ['final_score'=>$final_score,'per_order_ctedit'=>$per_order_ctedit,'credit_scale'=>$credit_scale];
}

//单独判断积分的开关情况
function integral_switch($web_id,$lang_id){
    //判断积分开启情况
    $wheresql = 'web_id='.$web_id.' and lang_id ='.$lang_id;
    $credit_config = model('member/MemberCredit')->get_config($wheresql,'is_open_credit,is_shopping_interaction,credit_scale,proportion');
    
    return $credit_config;
}

//兑换积分后会员积分扣减
function dedu_integral($data){
    $switch = integral_switch($data['web_id'],$data['lang_id']);//获取积分开关情况
    if($switch['is_open_credit'] ==1 && $switch['is_shopping_interaction'] ==1){//如果同时开启了积分和消费积分
        $consume_credit = db('member',[],false)->where(['uid'=>$data['uid']])->value('consume_credit');//获取uid的消费积分
        $consume_credit = ($consume_credit - $data['final_score']);
        //消耗的消费积分记录日志
        $credit_log['consumer_credit'] = $data['final_score'];
        $credit_log['interact_credit'] = 0;
        //消耗的消费积分记录日志
        db('member',[],false)->where(['uid'=>$data['uid']])->update(['consume_credit'=>$consume_credit]);//更新消费积分
    }elseif($switch['is_open_credit'] ==1 && $switch['is_shopping_interaction'] ==0){//如果只开启了积分，那么积分=消费积分+互动积分
        $all_credit = db('member',[],false)->where(['uid'=>$data['uid']])->field('consume_credit,interact_credit')->find();//获取uid的消费积分和互动积分
        if($data['final_score'] > $all_credit['consume_credit']){//如果消费积分不够扣
            $consume_credit = ($all_credit['consume_credit']+$all_credit['interact_credit'])-$data['final_score'];
            db('member',[],false)->where(['uid'=>$data['uid']])->update(['consume_credit'=>0,'interact_credit'=>$consume_credit]);//更新互动积分
            //消耗的消费积分记录日志
            $credit_log['consumer_credit'] = $all_credit['consume_credit'];
            $credit_log['interact_credit'] = $data['final_score'] - $all_credit['consume_credit'];
            //消耗的消费积分记录日志
        }else{
            $consume_credit = $all_credit['consume_credit'] - $data['final_score'];
            db('member',[],false)->where(['uid'=>$data['uid']])->update(['consume_credit'=>$consume_credit]);//更新消费积分
            //消耗的消费积分记录日志
            $credit_log['consumer_credit'] = $data['final_score'];
            $credit_log['interact_credit'] = 0;
            //消耗的消费积分记录日志
        }
    }
    
    $credit_param=[
        'web_id'=>$data['web_id'],
        'lang_id'=>$data['lang_id'],
        'uid'=>$data['uid'],
        'type'=>1,
        'order_no'=>$data['order_no'],
        'credit'=>"-".$data['final_score'],
        'remark'=> get_lang('CREDIT_EXCHANGE',['order_no'=> $data['order_no'],'score'=>$data['final_score']],$data['lang_id']),
        'order_status'=>'o0',//订单状态
    ];
    $param = array_merge($credit_log??[],$credit_param);
    $creditMod = new \app\member\model\MemberCredit();
    $creditMod->create_credit_log($param,false);
}

/**
 * 缓存配置缓存
 */
function domain_set_cache($data=[]){
    if(empty($data)){
        //第一次缺失,主动查库
        $data = think\Db::connect(config('database.db_config2'))->name('DomainSet')->select();
        $new_data = [];
        foreach ($data as $key=>$value){
            $new_data[$value['k']] = $value['v'];
        }
        $data = $new_data;
    }
//    echo json_encode($data);die;
    cache('domain_set',$data,get_cache_path(false));
}

/**
 * 初始化订单配置
 */
function initial_orderset($web_id,$lang_id=1){
    if(isset($web_id)&&isset($lang_id)){
        $getId = db('OrderSet')->where(['web_id'=>$web_id,'lang_id'=>$lang_id])->value('id');
        if(!$getId){
            $save = [
                'web_id'=>$web_id,
                'lang_id'=>$lang_id,
                'deadline'=>2,
                'autoconfirm'=>3,
                'prompt_email'=>0,
                'prompt_sms'=>0,
                'prompt_msg'=>0
            ];
            $ok = db('OrderSet')->insert($save);
        }
        return true;
    }else{
        return false;
    }
}

/**
 * 鸭梨内部应用列表
 */
function yali_service_cache(){
    $mall_domain = \app\common\model\Base::get_domain_set('mall_domain',1);
    $output = \app\common\model\Base::curl_post($mall_domain.'/api/oauth_service/get_service_model',[]);
    $output = \app\common\model\Base::curl_post($mall_domain.'/api/oauth_service/get_service_model',[]);
    $output = \app\common\model\Base::object_array($output);
    $new_business = [];
    if(!empty($output['data'])){
        $business_type = lang_config('business_type');
        foreach($output['data'] as $key=>$value){
            if(!empty($value['model_type']) && 10 != $value['model_type']){
                $value['type'] = $value['model_type'];
                $value['business_type'] = !empty($business_type[$value['type']]['type'])?$business_type[$value['type']]['type']:'';
                unset($value['model_type']);
                //业务所有的事件
                $value['events'] = [];
                $new_business[$value['business_type']] = $value;
            }
        }
    }
    cache('yali_service',!empty($new_business)?$new_business:null,get_cache_path(false));
}
function mkdirs($dir){
    if(!is_dir($dir)){
        if(!mkdirs(dirname($dir))){
            return false;
        }
        if(!mkdir($dir,0777,true)){
            return false;
        }
        chmod($dir, 0777);
    }
    return true;
}
function assemble_cate_cache(){
    $mall_domain = \app\common\model\Base::get_domain_set('mall_domain',1);
    $output = \app\common\model\Base::curl_post($mall_domain.'/api/web/web_templte_category',[]);
    $output = \app\common\model\Base::object_array($output);
    $assemble_cate = [];
    if(!empty($output) && $output['code'] > 0){
        if(!empty($output['data'])){
            foreach ($output['data'] as $key=>$value){
                $new['id'] = $value['id'];
                $new['name'] = $value['name']??'';
                $new['pid'] = $value['pid']??'';
                $new['tag_type'] = (int)$value['tag_type']??'';
                $new['web_type'] = $value['web_type']??'';
                $new['thumb'] = $value['thumb']??'';
                $assemble_cate[$value['type']][] = $new;
            }
        }else{
            $assemble_cate = [];
        }
    }
    cache('assemble_cate',!empty($assemble_cate)?$assemble_cate:null,get_cache_path(false));
}
function region_pinyin_cache(){
    $list  = think\Db::connect(config('database.db_config2'))->name('region')->where(['pinyin'=>['neq','']])->order('id asc')->select();
    if(!empty($list)){
        $list = array_column($list,'id','pinyin');
    }
    cache('region_pinyin',!empty($list)?$list:null,get_cache_path(false));
}
/***
 *门店组织缓存
 */
function multishop_group_cache(){
    // return 111;
    $where['web_id'] = config('web_id');
    $where['lang_id'] = config('lang_id');
    $where['is_delete'] = 0;
    $list = db('MultishopGroup')->where($where)->order('sort DESC,add_time DESC')->field('id,web_id,lang_id,pid,name,sort,add_time')->select();
    cache( 'multishop_group_list_'.$where['lang_id'], $list,get_cache_path());
}

/***
 * 系统权限缓存
 * $type 为空则读取列表、为dictionary则读取字典、为reset则重置缓存
 */
function system_power_cache($type='',$identify='',$site_type=''){
//    $list = take_cache('system_power_list');
      $list = [];
    if(!$list || $type == 'reset'){
        $where['web_id'] = 0;
        $where['status'] = 1;
        $list = db('FrontPower')->where(['web_id'=>0,'status'=>1,'member_type'=>$identify,'site_type'=>$site_type])->order('id ASC')->field('id,pid,name,type,flag')->select();
        cache( 'system_power_list_1', $list,get_cache_path());
    }
    if(!$type){
        return $list;
    }elseif($type == 'dictionary'){
        $lists = [];
        foreach($list as $k=>$v){
            $lists[$v['id']] = $v;
        }
        return $lists;
    }
}
